/* eslint no-console: 0 */
import React, {PropTypes} from 'react';
import {findDOMNode} from 'react-dom';
import {Row, Spin, Alert} from 'antd';
import {getDOMHeight} from './util';
import _ from 'lodash';

export function Busy(props) {
    return (
        <Row className="center">
            <Spin size={props.size} tip={props.text}/>
        </Row>
    );
}

export function Fail(props) {
    return <Alert type="error" message={props.error}/>;
}

// 处理加载状态、错误信息等通用功能的React组件基类
export default class Base extends React.Component {
    static contextTypes = {
        router: PropTypes.object,
        location: PropTypes.object,
        params: PropTypes.object,
        routes: PropTypes.array
    };

    constructor(props, context) {
        super(props, context);
        this.root = 'data';
        // 子类实现init方法，设置this.root和this.data
        if (typeof this.init === 'function') {
            this.init(props, context);
        }
    }

    componentDidMount() {
        this._mounted = true;
        this.dom = findDOMNode(this);
        if (this.setMaxHeight) {
            const self = this;
            $(window).resize(() => {
                if (self._mounted) {
                    self.setMaxHeight();
                }
            });
        }
        if (typeof this.mount === 'function') {
            this.mount();
        }
        if (typeof this.update === 'function') {
            this.update();
        }
    }

    componentDidUpdate() {
        this.dom = findDOMNode(this);
        if (this.setMaxHeight) {
            this.setMaxHeight();
        }
        if (typeof this.update === 'function') {
            this.update();
        }
    }

    componentWillUnmount() {
        if (typeof this.umount === 'function') {
            this.umount();
        }
        this.dom = undefined;
        this._mounted = false;
    }

    // 最大可用高度（主页面区域高度减去兄弟节点高度，仅适用于顶层布局对象）
    maxHeight() {
        const dom = $(findDOMNode(this));
        const selfHeight = getDOMHeight(dom);
        const parentHeight = getDOMHeight(dom.parent());
        const siblingsHeight = parentHeight - selfHeight;
        return global.app.main.height - siblingsHeight;
    }

    busy(text, size) {
        return <Busy text={text} size={size}/>;
    }

    fail(error) {
        return <Fail error={error}/>;
    }

    error(errors) {
        let message;
        if (Array.isArray(errors)) {
            message = _.map(errors, error => error.message).join(' ');
        } else if ('message 'in errors) {
            message = errors.message;
        } else {
            message = errors.toString();
        }
        return message;
    }

    render() {
        if (typeof this.root === 'string' &&
            typeof this.data === 'string') {
            const root = this.props[this.root];
            const {loading, errors} = root;
            const data = root[this.data];
            if (loading) {
                return this.busy(this.loadingText, this.loadingSize);
            }
            if (errors) {
                return this.fail(this.error(errors));
            }
            if (data) {
                return this.done(data);
            }
            return null;
        } else {
            if (console && console.warn) {
                console.warn('NO this.data specified');
            }
        }
    }
}
